home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / src / kill.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-13  |  1.7 KB  |  75 lines

  1. #include "amiga.h"
  2. #include "signals.h"
  3. #include "processes.h"
  4. #include <exec/execbase.h>
  5.  
  6. extern struct ExecBase *SysBase;
  7.  
  8. static void break_list(struct List *tasks, BPTR fh)
  9. {
  10.     struct Process *p;
  11.  
  12.     for (p = (struct Process *) tasks->lh_Head; p->pr_Task.tc_Node.ln_Succ;
  13.      p = (struct Process *) p->pr_Task.tc_Node.ln_Succ) {
  14.     if (p->pr_Task.tc_Node.ln_Type == NT_PROCESS) {
  15.         struct CommandLineInterface *cli = p->pr_CLI ? BADDR(p->pr_CLI) : 0;
  16.  
  17.         if (p->pr_CIS == fh || p->pr_COS == fh || p->pr_CES == fh ||
  18.         cli && (cli->cli_StandardInput == fh || cli->cli_CurrentInput == fh ||
  19.             cli->cli_StandardOutput == fh || cli->cli_CurrentOutput == fh))
  20.         Signal(p, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
  21.     }
  22.     }
  23. }
  24.  
  25. static int magickill(BPTR fh, int signo)
  26. {
  27.     switch (signo) {
  28.     case SIGINT:
  29.     case SIGQUIT:
  30.     case SIGKILL:
  31.     case SIGHUP:
  32.         Forbid();
  33.         break_list(&SysBase->TaskReady, fh);
  34.         break_list(&SysBase->TaskWait, fh);
  35.         Permit();
  36.         return 0;
  37.     default:
  38.         errno = EINVAL;
  39.         return -1;
  40.     }
  41. }
  42.  
  43. int kill(int pid, int signal)
  44. {
  45.     __chkabort();
  46.     /* Our process list is now reasonably upto date */
  47.     if (pid < 0)
  48.     pid = -pid;    /* Consider that each process is a pg onto itself */
  49.     if (pid == _our_pid) {
  50.     if (signal)
  51.         _sig_dispatch(signal);
  52.     return 0;
  53.     } else {
  54.     struct process *entry;
  55.     int killrc;
  56.  
  57.     entry = _find_pid(pid);
  58.     if (!entry || entry->status != alive) {
  59.         errno = ESRCH;
  60.         return -1;
  61.     }
  62.     if (!signal)
  63.         return 0;
  64.     killrc = magickill(entry->input, signal);
  65.     if (signal == SIGKILL) {
  66.         /* Fake the kill from emacs point of view */
  67.         entry->status = exited;
  68.         entry->rc = SIGKILL;
  69.         _sig_dispatch(SIGCHLD);
  70.         return 0;
  71.     }
  72.     return killrc;
  73.     }
  74. }
  75.